{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 引入包\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import pickle \n",
    "import time\n",
    "import matplotlib.pyplot\n",
    "%matplotlib inline"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "f=open('train_data.fms','rb')\n",
    "train_data=pickle.load(f)    \n",
    "f.close()\n",
    "\n",
    "f=open('test_data.fms','rb')\n",
    "test_data=pickle.load(f)    \n",
    "f.close()\n",
    "\n",
    "f=open('train_label.fms','rb')\n",
    "train_label=pickle.load(f)    \n",
    "f.close()\n",
    "\n",
    "f=open('test_label.fms','rb')\n",
    "test_label=pickle.load(f)    \n",
    "f.close()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 定义神经网络"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "class neuralNetwork:\n",
    "    def __init__(self, inputnodes, hiddennodes, outputnodes, learningrate):\n",
    "        \n",
    "        self.inodes = inputnodes\n",
    "        self.hnodes = hiddennodes\n",
    "        self.onodes = outputnodes\n",
    "  \n",
    "        self.wih = np.random.normal(0.0, pow(self.inodes, -0.5), (self.hnodes, self.inodes))\n",
    "        self.who = np.random.normal(0.0, pow(self.hnodes, -0.5), (self.onodes, self.hnodes))\n",
    "        \n",
    "        self.lr = learningrate\n",
    "        \n",
    "        self.activation_function = lambda x: 1 / (1 + np.exp(-x))           \n",
    "        pass\n",
    "    \n",
    "    def train(self, inputs_list, targets_list):\n",
    "            \n",
    "        inputs = np.array(inputs_list, ndmin=2).T\n",
    "        targets = np.array(targets_list, ndmin=2).T\n",
    "        \n",
    "        hidden_inputs = np.dot(self.wih, inputs)\n",
    "        hidden_outputs = self.activation_function(hidden_inputs)\n",
    "        \n",
    "        final_inputs = np.dot(self.who, hidden_outputs)\n",
    "        final_outputs = self.activation_function(final_inputs)\n",
    "        \n",
    "        output_errors = targets - final_outputs\n",
    "        hidden_errors = np.dot(self.who.T, output_errors) \n",
    "        \n",
    "        gho=np.dot((output_errors * final_outputs * (1.0 - final_outputs)), np.transpose(hidden_outputs))  \n",
    "        gih=np.dot((hidden_errors * hidden_outputs * (1.0 - hidden_outputs)), np.transpose(inputs)) \n",
    "\n",
    "        \n",
    "        self.who += self.lr * gho      \n",
    "        self.wih += self.lr * gih         \n",
    "        pass\n",
    "    \n",
    "    def query(self, inputs_list):\n",
    "        inputs = np.array(inputs_list, ndmin=2).T\n",
    "        hidden_inputs = np.dot(self.wih, inputs)\n",
    "        hidden_outputs = self.activation_function(hidden_inputs)\n",
    "        \n",
    "        final_inputs = np.dot(self.who, hidden_outputs)\n",
    "        final_outputs = self.activation_function(final_inputs)\n",
    "        \n",
    "        return final_outputs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "+ 设定参数 \n",
    "\n",
    "|输入数据长度|  隐藏层宽度|  输出长度|  学习率|  \n",
    "|----|  ----|  ---- |  ----|   \n",
    "|  input_nodes|   hidden_nodes|   output_nodes|   learning_rate| \n",
    "|784|200|10|0.1|\n",
    "|不能变|可以变|不能变|可以变|"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "input_nodes = 784\n",
    "hidden_nodes = 200\n",
    "output_nodes = 10\n",
    "\n",
    "learning_rate = 0.1\n",
    "\n",
    "n = neuralNetwork(input_nodes,hidden_nodes,output_nodes, learning_rate)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "1. 读取数据"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "训练5遍"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "epochs = 1\n",
    "m=0\n",
    "for e in range(epochs):\n",
    "    start=time.time()\n",
    "    for i in range(60000):\n",
    "        inputs=train_data[i]\n",
    "        targets=train_label[i]\n",
    "        n.train(inputs, targets)\n",
    "        m=m+1\n",
    "        if m%1000==0:\n",
    "            print(\".\",end=\"\")\n",
    "        pass\n",
    "    print(time.time()-start)\n",
    "    pass"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "读取测试数据"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运行看看效果"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "performance =  0.973\n"
     ]
    }
   ],
   "source": [
    "scorecard = []\n",
    "\n",
    "for i in range(10000):\n",
    "    inputs=test_data[i]\n",
    "    correct_label=test_label[i]\n",
    "    outputs = n.query(inputs)\n",
    "    label = numpy.argmax(outputs)\n",
    "    if (label == correct_label):\n",
    "        scorecard.append(1)\n",
    "    else:\n",
    "        scorecard.append(0)\n",
    "        pass\n",
    "    pass\n",
    "\n",
    "scorecard_array = numpy.asarray(scorecard)\n",
    "print (\"performance = \", scorecard_array.sum() / scorecard_array.size)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "结果"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
